#include "FriendStation.h"

boolean IsEmptyMemberList (MemberList L)
/* I.S sembarang
	Mengembalikan nilai true jika MemberList kosong */
{
	return (L==Nil);
}

boolean IsEmptyFriendList (FriendList L)
/* I.S sembarang
	Mengembalikan nilai true jika FriendList kosong */
{
	return (F==Nil);
}

address Alokasi (InfoUser ID)
/* Mengirimkan address hasil alokasi sebuah elemen */
/* Jika alokasi berhasil, maka address tidak nil, dan misalnya menghasilkan P */
/* Jika alokasi gagal, mengirimkan Nil */
{
	address P;
	*P = (address) malloc (sizeof(MemberList));
	if((*P) != Nil)
	{
		Info(*P) = ID;
		Next(*P) = Nil;
	}
	return P;
}

void Dealokasi (address P)
/* I.S. P terdefinisi */
/* F.S. P dikembalikan ke sistem */
/* Melakukan dealokasi/pengembalian address P */
{	
	free(P);
}

void AddUser (MemberList *U, InfoUser ID)
/*     I.S email USER belum terdefinisi di U. U mungkin kosong.
    F.S Insert USER sebagai elemen terakhir dari U dengan urut membesar berdasarkan Nama
    AddUser menggunakan procedure InsSort (menyisipkan user baru dengan terurut membesar berdasarkan nama)    
*/
{
	address P;
	Alokasi (&P, ID);
	if (P!=Nil)
	{
		if (IsEmpty(*U))
		{
			U = P;
		}
		else
		{
			PC = P;			
			if (strcmp(Info(P).Nama,PC.Nama)==(-1))
			{
				Next(ID) = U;
				First(U) = P;
			}	
			else
			{
				while ((Next(PC)!= Nil) && ((strcmp(PC.Nama, Info(P).Nama)==(-1) )|| ((strcmp(PC.Nama, Info(P).Nama)==0))))
				{
					PC= Next(PC);
				}
				Next(P)= Next(PC);
				Next(PC) = P;
			}
		}
	}
}

void DelUser (MemberList *U, string E)
/*  I.S E terdefinisi di U
    F.S Data pribadi (nama, tanggal lahir, kota asal, universitas, SMU) dari pengguna yang beralamat-email E dihapus.
    Perintah ini harus menjamin integrity dari seluruh data (seperti friend relations) */
{
	address P,C;
	P= SearchFriend(*U,L);
	C=*U;
	while (C!=Nil)
	{
		Unfriend(*U.Friends,E);
		C=Next(C);
	}
	C=*U;
	if (strcmp(Info(C).Email,E)== 0)
			U= Next(First(U));
	else
	{
		while ((strmpc(Info(Next(C)).Email,E)!=0) && (Next(C)!=Nil))
			C= Next(C);
		if (Next(C)!=Nil)
		{	
			(*U)=Next(*U);
			Dealokasi(C);
		}
	}	
	
}

address AlokasiF (Info ID)
/* Mengirimkan address hasil alokasi sebuah elemen */
/* Jika alokasi berhasil, maka address tidak nil, dan misalnya menghasilkan P */
/* Jika alokasi gagal, mengirimkan Nil */
{
	address P;
	*P = (address) malloc (sizeof(FriendList));
	if((*P) != Nil)
	{
		Info(*P) = ID;
		Next(*P) = Nil;
	}
	return P;
}
	
address SearchFriend (MemberList *U,string UserId);
/* mengembalikan alamat dari UserId di dalam MemberList */ 	
{
	address P;
	P = (*L);
	while ((!found) && (P!=Nil))
	{
		if (strcmp(P.Email, UserId)== 0){
			found=true;}
		else{
			P=Next(P);}
	}
}
	
void Friend (MemberList *L, FriendList *F, string UserId)
/*    I.S UserId bisa kosong, atau berisi email orang lain
    F.S Jika UserId kosong : tampilkan semua 1st friend dari CurrentUser
		Jika UserId berisi alamat email orang lain, pengguna dengan UserId tersebut ditambahkan sebagai 1st friend dari CurrentUser
*/
{
	address P, PC, PF;
	if (UserId == "")
	{
		if (IsEmptyFriendList(*F))
			printf("CurrentUser tidak memiliki 1st friend.\n");
		else
		{
			printf("Daftar 1st friend dari current user adalah .\n");
			P=(*F);
			while (P!=Nil)
			{
				printf ("%s\n",P.Email);
			}
		}
	}
	else
	{
		
		if (IsEmpty(*F))
		{
			F = P;
		}
		else
		{
			if (IsFound(*L, Email, UserId))
			{
				PF = SearchFriend(*L,UserId);
				AlokasiF (&P,PF);
				PC = F;			
				if ((strcmp(Info(PF).Nama, PC.Nama)==(-1) ))
				{
					Next(P) = F;
					First(F) = P;
				}	
				else
				{
					while ((Next(PC)!= Nil) && ((strcmp(PC.Nama, Info(PF).Nama)==(-1) )|| ((strcmp(PC.Nama, Info(PF).Nama)==0))))
					{
						PC= Next(PC);
					}
					Next(P)= Next (PC);
					Next(PC) = P;
				}
			}
			else
				printf("User_ID %s tidak terdaftar sebagai user\n",UserId);
		}
	}
}
 
void UnFriend (FriendList *F, string UserId)
/*    I.S UserId tidak kosong dan merupakan 1st friend dari CurrentUser
    F.S Hubungan pertemanan antara CurrentUser dan UserId dihapus
*/
{
	address C,PF;
	PF = SearchFriend(*L,UserId);
	C=(*F);
	if (Info(C)==PF)
		U= Next(First(U));
	else
	{
		while ((Info(Next(C)!=PF) && (Next(C)!=Nil))
			C= Next(C);
		if (Next(C)!=Nil)
		{	
			(*F)=Next(*F);
			Dealokasi(C);
		}
	}	
}

boolean IsFound (MemberList *L, string field, string S)
/*    I.S    S, field, dan L terdefinisi
			Field adalah Email/Nama/TglLahir/KotaAsal/Universitas/SMU
			F.S    mengembalikan true jika S ditemukan pada L
    (note : bila field adalah Nama, S berisi Joko, Ina, dll [misal])
*/
{
	boolean found=false;
	address P;
	switch (field){
	"Email" : { P = (*L);
				while ((!found) && (P!=Nil))
				{
					if (strcmp(Info(P).Email,S)==0){
						found=true;}
					else{
						P=Next(P);}
				}
				break;
			}
	"Nama" : { P = (*L);
				while ((!found) && (P!=Nil))
				{
					if (strcmp(Info(P).Nama,S)==0){
						found=true;}
					else{
						P=Next(P);}
				}
				break;
			}			
	"TglLahir" : { P = (*L);
				while ((!found) && (P!=Nil))
				{
					if (strcmp(Info(P).TglLahir,S)==0){
						found=true;}
					else{
						P=Next(P);}
				}
				break;
			}
	"KotaAsal" : { P = (*L);
				while ((!found) && (P!=Nil))
				{
					if (strcmp(Info(P).KotaAsal,S)==0){
						found=true;}
					else{
						P=Next(P);}
				}
				break;
			}	
	"Universitas" : { P = (*L);
				while ((!found) && (P!=Nil))
				{
					if (strcmp(Info(P).Universitas,S)==0){
						found=true;}
					else{
						P=Next(P);}
				}
				break;
			}
	"SMU" : { P = (*L);
				while ((!found) && (P!=Nil))
				{
					if (strcmp(Info(P).SMU,S)==0){
						found=true;}
					else{
						P=Next(P);}
				}
				break;
			}				
	}
	return found;
}

void  List (MemberList *U, string Field, string state);
/*    I.S U tidak kosong
    F.S isi U ditampilkan sesuai state (asc/desc) berdasarkan Field tertentu (email/nama/tgl lahir/kota asal/universitas/SMU)
    Secara default, List akan ditampilakn daftar semua pengguna terurut asc berdasarkan Nama.
    Keterangan : asc : menampilkan data dalam keadaan terurut membesar
               desc: menampilkan data dalam keadaan terurut mengecil */